import { getBusinessObject, is, isAny } from 'bpmn-js/lib/util/ModelUtil'
import { useSettingStore } from '@/store/bpmnProcess/settingStore'
import { useModelerStore } from '@/store/bpmnProcess/modelerStore'
import { getExtensionElementsList, addExtensionElements, removeExtensionElements } from './bpmnPropertyUtils/extensionElements'
import { createScript } from './scriptType'

export function isTaskListener(element): boolean {
  return is(element, 'bpmn:UserTask')
}

const listenerAllowedTypes = ['bpmn:Activity', 'bpmn:Event', 'bpmn:Gateway', 'bpmn:SequenceFlow', 'bpmn:Process', 'bpmn:Participant']
export function isExecuteListener(element): boolean {
  if (isAny(element, listenerAllowedTypes)) return true
  if (is(element, 'bpmn:Participant')) {
    return !!element.businessObject.processRef
  }
  return false
}

// 获取监听器列表
export function getListeners(element, type) {
  const prefix = useSettingStore().editor.processEngine
  const businessObject = getListenersContainer(element)
  return getExtensionElementsList(businessObject, `${prefix}:${type}`)
}

// 添加监听器
export function addListener(element, type, props) {
  const prefix = useSettingStore().editor.processEngine
  const moddle = useModelerStore().getModdle
  const listener = moddle!.create(`${prefix}:${type}`, {})
  const businessObject = getListenersContainer(element)
  updateListenerProperty(element, listener, props)
  addExtensionElements(element, businessObject, listener)
}

// 更新监听器
export function updateListener(element, type, props, listener) {
  removeExtensionElements(element, getListenersContainer(element), listener)
  addListener(element, type, props)
}

// 移除监听器
export function removeListener(element, listener) {
  removeExtensionElements(element, getListenersContainer(element), listener)
}

export function getListenerType(listener, type): string {
  const prefix = useSettingStore().editor.processEngine
  if (isAny(listener, [`${prefix}:${type}`])) {
    if (listener.get(`${prefix}:class`)) return 'class'
    if (listener.get(`${prefix}:expression`)) return 'expression'
    if (listener.get(`${prefix}:delegateExpression`)) return 'delegateExpression'
    if (listener.get('script')) return 'script'
  }
  return ''
}

export function getDefaultEvent(element, type) {
  if (type === 'TaskListener') return 'create'
  return is(element, 'bpmn:SequenceFlow') ? 'take' : 'start'
}

export function getListenerEventTypeOptions(element, type) {
  if (type === 'TaskListener') {
    return [
      { value: 'create', label: '创建' },
      { value: 'assignment', label: '分配' },
      { value: 'complete', label: '完成' },
      { value: 'delete', label: '删除' },
      { value: 'update', label: '更新' },
      { value: 'timeout', label: '暂停' }
    ]
  }
  if (is(element, 'bpmn:SequenceFlow')) {
    return [{ label: '引导', value: 'take' }]
  }
  return [
    { label: '开始', value: 'start' },
    { label: '结束', value: 'end' }
  ]
}

export function getListenerEventTypeObject() {
  return {
    take: '引导',
    start: '开始',
    end: '结束',
    create: '创建',
    assignment: '分配',
    complete: '完成',
    delete: '删除',
    update: '更新',
    timeout: '暂停'
  }
}

export function getListenerTypeOptions() {
  return [
    { label: 'Java 类', value: 'class' },
    { label: '表达式', value: 'expression' },
    { label: '代理表达式', value: 'delegateExpression' },
    { label: '脚本', value: 'script' }
  ]
}

export function getListenerTypeObject() {
  return {
    class: 'Java 类',
    expression: '表达式',
    delegateExpression: '代理表达式',
    script: '脚本'
  }
}

// helper
export function getListenersContainer(element) {
  const businessObject = getBusinessObject(element)
  return businessObject?.get('processRef') || businessObject
}

function updateListenerProperty(element, listener, props) {
  const modeling = useModelerStore().getModeling
  const prefix = useSettingStore().editor.processEngine
  const { event, id, class: listenerClass, expression, delegateExpression, script, type, fields } = props

  const updateProperty = (key, value) => modeling.updateModdleProperties(element, listener, { [`${prefix}:${key}`]: value })

  event && updateProperty('event', event)
  id && updateProperty('id', id)
  listenerClass && updateProperty('class', listenerClass)
  expression && updateProperty('expression', expression)
  delegateExpression && updateProperty('delegateExpression', delegateExpression)
  console.log(props)

  if (script) {
    const bpmnScript = createScript(script)
    modeling.updateModdleProperties(element, listener, { script: bpmnScript })
  }

  if (fields) {
    const bpmnFields = fields.map((field: any) => {
      return createFieldObject(field)
    })
    modeling.updateModdleProperties(element, listener, { fields: bpmnFields })
  }
}

// 创建 监听器的注入字段 实例
export function createFieldObject(option) {
  const moddle = useModelerStore().getModdle
  const prefix = useSettingStore().editor.processEngine
  const { name, fieldType, string, expression } = option
  const fieldConfig = fieldType === 'string' ? { name, string } : { name, expression }
  return moddle.create(`${prefix}:Field`, fieldConfig)
}
